home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2000 March / maximum-cd-2000-03.iso / Quake3 Game Source / Q3AGameSource.exe / Main / g_svcmds.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-18  |  8.2 KB  |  450 lines

  1. // Copyright (C) 1999-2000 Id Software, Inc.
  2. //
  3.  
  4. // this file holds commands that can be executed by the server console, but not remote clients
  5.  
  6. #include "g_local.h"
  7.  
  8.  
  9. /*
  10. ==============================================================================
  11.  
  12. PACKET FILTERING
  13.  
  14.  
  15. You can add or remove addresses from the filter list with:
  16.  
  17. addip <ip>
  18. removeip <ip>
  19.  
  20. The ip address is specified in dot format, and any unspecified digits will match any value, so you can specify an entire class C network with "addip 192.246.40".
  21.  
  22. Removeip will only remove an address specified exactly the same way.  You cannot addip a subnet, then removeip a single host.
  23.  
  24. listip
  25. Prints the current list of filters.
  26.  
  27. g_filterban <0 or 1>
  28.  
  29. If 1 (the default), then ip addresses matching the current list will be prohibited from entering the game.  This is the default setting.
  30.  
  31. If 0, then only addresses matching the list will be allowed.  This lets you easily set up a private game, or a game that only allows players from your local network.
  32.  
  33.  
  34. ==============================================================================
  35. */
  36.  
  37. // extern    vmCvar_t    g_banIPs;
  38. // extern    vmCvar_t    g_filterBan;
  39.  
  40.  
  41. typedef struct ipFilter_s
  42. {
  43.     unsigned    mask;
  44.     unsigned    compare;
  45. } ipFilter_t;
  46.  
  47. #define    MAX_IPFILTERS    1024
  48.  
  49. static ipFilter_t    ipFilters[MAX_IPFILTERS];
  50. static int            numIPFilters;
  51.  
  52. /*
  53. =================
  54. StringToFilter
  55. =================
  56. */
  57. static qboolean StringToFilter (char *s, ipFilter_t *f)
  58. {
  59.     char    num[128];
  60.     int        i, j;
  61.     byte    b[4];
  62.     byte    m[4];
  63.     
  64.     for (i=0 ; i<4 ; i++)
  65.     {
  66.         b[i] = 0;
  67.         m[i] = 0;
  68.     }
  69.     
  70.     for (i=0 ; i<4 ; i++)
  71.     {
  72.         if (*s < '0' || *s > '9')
  73.         {
  74.             G_Printf( "Bad filter address: %s\n", s );
  75.             return qfalse;
  76.         }
  77.         
  78.         j = 0;
  79.         while (*s >= '0' && *s <= '9')
  80.         {
  81.             num[j++] = *s++;
  82.         }
  83.         num[j] = 0;
  84.         b[i] = atoi(num);
  85.         if (b[i] != 0)
  86.             m[i] = 255;
  87.  
  88.         if (!*s)
  89.             break;
  90.         s++;
  91.     }
  92.     
  93.     f->mask = *(unsigned *)m;
  94.     f->compare = *(unsigned *)b;
  95.     
  96.     return qtrue;
  97. }
  98.  
  99. /*
  100. =================
  101. UpdateIPBans
  102. =================
  103. */
  104. static void UpdateIPBans (void)
  105. {
  106.     byte    b[4];
  107.     int        i;
  108.     char    iplist[MAX_INFO_STRING];
  109.  
  110.     *iplist = 0;
  111.     for (i = 0 ; i < numIPFilters ; i++)
  112.     {
  113.         if (ipFilters[i].compare == 0xffffffff)
  114.             continue;
  115.  
  116.         *(unsigned *)b = ipFilters[i].compare;
  117.         Com_sprintf( iplist + strlen(iplist), sizeof(iplist) - strlen(iplist), 
  118.             "%i.%i.%i.%i ", b[0], b[1], b[2], b[3]);
  119.     }
  120.  
  121.     trap_Cvar_Set( "g_banIPs", iplist );
  122. }
  123.  
  124. /*
  125. =================
  126. G_FilterPacket
  127. =================
  128. */
  129. qboolean G_FilterPacket (char *from)
  130. {
  131.     int        i;
  132.     unsigned    in;
  133.     byte m[4];
  134.     char *p;
  135.  
  136.     i = 0;
  137.     p = from;
  138.     while (*p && i < 4) {
  139.         m[i] = 0;
  140.         while (*p >= '0' && *p <= '9') {
  141.             m[i] = m[i]*10 + (*p - '0');
  142.             p++;
  143.         }
  144.         if (!*p || *p == ':')
  145.             break;
  146.         i++, p++;
  147.     }
  148.     
  149.     in = *(unsigned *)m;
  150.  
  151.     for (i=0 ; i<numIPFilters ; i++)
  152.         if ( (in & ipFilters[i].mask) == ipFilters[i].compare)
  153.             return g_filterBan.integer != 0;
  154.  
  155.     return g_filterBan.integer == 0;
  156. }
  157.  
  158. /*
  159. =================
  160. AddIP
  161. =================
  162. */
  163. static void AddIP( char *str )
  164. {
  165.     int        i;
  166.  
  167.     for (i = 0 ; i < numIPFilters ; i++)
  168.         if (ipFilters[i].compare == 0xffffffff)
  169.             break;        // free spot
  170.     if (i == numIPFilters)
  171.     {
  172.         if (numIPFilters == MAX_IPFILTERS)
  173.         {
  174.             G_Printf ("IP filter list is full\n");
  175.             return;
  176.         }
  177.         numIPFilters++;
  178.     }
  179.     
  180.     if (!StringToFilter (str, &ipFilters[i]))
  181.         ipFilters[i].compare = 0xffffffffu;
  182.  
  183.     UpdateIPBans();
  184. }
  185.  
  186. /*
  187. =================
  188. G_ProcessIPBans
  189. =================
  190. */
  191. void G_ProcessIPBans(void) 
  192. {
  193.     char *s, *t;
  194.     char        str[MAX_TOKEN_CHARS];
  195.  
  196.     Q_strncpyz( str, g_banIPs.string, sizeof(str) );
  197.  
  198.     for (t = s = g_banIPs.string; *t; /* */ ) {
  199.         s = strchr(s, ' ');
  200.         if (!s)
  201.             break;
  202.         while (*s == ' ')
  203.             *s++ = 0;
  204.         if (*t)
  205.             AddIP( t );
  206.         t = s;
  207.     }
  208. }
  209.  
  210.  
  211. /*
  212. =================
  213. Svcmd_AddIP_f
  214. =================
  215. */
  216. void Svcmd_AddIP_f (void)
  217. {
  218.     char        str[MAX_TOKEN_CHARS];
  219.  
  220.     if ( trap_Argc() < 2 ) {
  221.         G_Printf("Usage:  addip <ip-mask>\n");
  222.         return;
  223.     }
  224.  
  225.     trap_Argv( 1, str, sizeof( str ) );
  226.  
  227.     AddIP( str );
  228.  
  229. }
  230.  
  231. /*
  232. =================
  233. Svcmd_RemoveIP_f
  234. =================
  235. */
  236. void Svcmd_RemoveIP_f (void)
  237. {
  238.     ipFilter_t    f;
  239.     int            i;
  240.     char        str[MAX_TOKEN_CHARS];
  241.  
  242.     if ( trap_Argc() < 2 ) {
  243.         G_Printf("Usage:  sv removeip <ip-mask>\n");
  244.         return;
  245.     }
  246.  
  247.     trap_Argv( 1, str, sizeof( str ) );
  248.  
  249.     if (!StringToFilter (str, &f))
  250.         return;
  251.  
  252.     for (i=0 ; i<numIPFilters ; i++) {
  253.         if (ipFilters[i].mask == f.mask    &&
  254.             ipFilters[i].compare == f.compare) {
  255.             ipFilters[i].compare = 0xffffffffu;
  256.             G_Printf ("Removed.\n");
  257.  
  258.             UpdateIPBans();
  259.             return;
  260.         }
  261.     }
  262.  
  263.     G_Printf ( "Didn't find %s.\n", str );
  264. }
  265.  
  266. /*
  267. ===================
  268. Svcmd_EntityList_f
  269. ===================
  270. */
  271. void    Svcmd_EntityList_f (void) {
  272.     int            e;
  273.     gentity_t        *check;
  274.  
  275.     check = g_entities+1;
  276.     for (e = 1; e < level.num_entities ; e++, check++) {
  277.         if ( !check->inuse ) {
  278.             continue;
  279.         }
  280.         G_Printf("%3i:", e);
  281.         switch ( check->s.eType ) {
  282.         case ET_GENERAL:
  283.             G_Printf("ET_GENERAL          ");
  284.             break;
  285.         case ET_PLAYER:
  286.             G_Printf("ET_PLAYER           ");
  287.             break;
  288.         case ET_ITEM:
  289.             G_Printf("ET_ITEM             ");
  290.             break;
  291.         case ET_MISSILE:
  292.             G_Printf("ET_MISSILE          ");
  293.             break;
  294.         case ET_MOVER:
  295.             G_Printf("ET_MOVER            ");
  296.             break;
  297.         case ET_BEAM:
  298.             G_Printf("ET_BEAM             ");
  299.             break;
  300.         case ET_PORTAL:
  301.             G_Printf("ET_PORTAL           ");
  302.             break;
  303.         case ET_SPEAKER:
  304.             G_Printf("ET_SPEAKER          ");
  305.             break;
  306.         case ET_PUSH_TRIGGER:
  307.             G_Printf("ET_PUSH_TRIGGER     ");
  308.             break;
  309.         case ET_TELEPORT_TRIGGER:
  310.             G_Printf("ET_TELEPORT_TRIGGER ");
  311.             break;
  312.         case ET_INVISIBLE:
  313.             G_Printf("ET_INVISIBLE        ");
  314.             break;
  315.         case ET_GRAPPLE:
  316.             G_Printf("ET_GRAPPLE          ");
  317.             break;
  318.         default:
  319.             G_Printf("%3i                 ", check->s.eType);
  320.             break;
  321.         }
  322.  
  323.         if ( check->classname ) {
  324.             G_Printf("%s", check->classname);
  325.         }
  326.         G_Printf("\n");
  327.     }
  328. }
  329.  
  330. gclient_t    *ClientForString( const char *s ) {
  331.     gclient_t    *cl;
  332.     int            i;
  333.     int            idnum;
  334.  
  335.     // numeric values are just slot numbers
  336.     if ( s[0] >= '0' && s[0] <= '9' ) {
  337.         idnum = atoi( s );
  338.         if ( idnum < 0 || idnum >= level.maxclients ) {
  339.             Com_Printf( "Bad client slot: %i\n", idnum );
  340.             return NULL;
  341.         }
  342.  
  343.         cl = &level.clients[idnum];
  344.         if ( cl->pers.connected == CON_DISCONNECTED ) {
  345.             G_Printf( "Client %i is not connected\n", idnum );
  346.             return NULL;
  347.         }
  348.         return cl;
  349.     }
  350.  
  351.     // check for a name match
  352.     for ( i=0 ; i < level.maxclients ; i++ ) {
  353.         cl = &level.clients[i];
  354.         if ( cl->pers.connected == CON_DISCONNECTED ) {
  355.             continue;
  356.         }
  357.         if ( !Q_stricmp( cl->pers.netname, s ) ) {
  358.             return cl;
  359.         }
  360.     }
  361.  
  362.     G_Printf( "User %s is not on the server\n", s );
  363.  
  364.     return NULL;
  365. }
  366.  
  367. /*
  368. ===================
  369. Svcmd_ForceTeam_f
  370.  
  371. forceteam <player> <team>
  372. ===================
  373. */
  374. void    Svcmd_ForceTeam_f( void ) {
  375.     gclient_t    *cl;
  376.     char        str[MAX_TOKEN_CHARS];
  377.  
  378.     // find the player
  379.     trap_Argv( 1, str, sizeof( str ) );
  380.     cl = ClientForString( str );
  381.     if ( !cl ) {
  382.         return;
  383.     }
  384.  
  385.     // set the team
  386.     trap_Argv( 2, str, sizeof( str ) );
  387.     SetTeam( &g_entities[cl - level.clients], str );
  388. }
  389.  
  390. /*
  391. =================
  392. ConsoleCommand
  393.  
  394. =================
  395. */
  396. qboolean    ConsoleCommand( void ) {
  397.     char    cmd[MAX_TOKEN_CHARS];
  398.  
  399.     trap_Argv( 0, cmd, sizeof( cmd ) );
  400.  
  401.     if ( Q_stricmp (cmd, "entitylist") == 0 ) {
  402.         Svcmd_EntityList_f();
  403.         return qtrue;
  404.     }
  405.  
  406.     if ( Q_stricmp (cmd, "forceteam") == 0 ) {
  407.         Svcmd_ForceTeam_f();
  408.         return qtrue;
  409.     }
  410.  
  411.     if (Q_stricmp (cmd, "game_memory") == 0) {
  412.         Svcmd_GameMem_f();
  413.         return qtrue;
  414.     }
  415.  
  416.     if (Q_stricmp (cmd, "addbot") == 0) {
  417.         Svcmd_AddBot_f();
  418.         return qtrue;
  419.     }
  420.  
  421.     if (Q_stricmp (cmd, "botlist") == 0) {
  422.         Svcmd_BotList_f();
  423.         return qtrue;
  424.     }
  425.  
  426.     if (Q_stricmp (cmd, "abort_podium") == 0) {
  427.         Svcmd_AbortPodium_f();
  428.         return qtrue;
  429.     }
  430.  
  431.     if (Q_stricmp (cmd, "addip") == 0) {
  432.         Svcmd_AddIP_f();
  433.         return qtrue;
  434.     }
  435.  
  436.     if (Q_stricmp (cmd, "removeip") == 0) {
  437.         Svcmd_RemoveIP_f();
  438.         return qtrue;
  439.     }
  440.  
  441.     if (Q_stricmp (cmd, "listip") == 0) {
  442.         trap_SendConsoleCommand( EXEC_INSERT, "g_banIPs\n" );
  443.         return qtrue;
  444.     }
  445.  
  446.  
  447.     return qfalse;
  448. }
  449.  
  450.